package code17_reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class TestConstructor {

	public static void main(String[] args) {
		//f1();
		
		Stu stu = initObject(Stu.class, "age", 333);
		System.out.println(stu);
	}

	private static void f1() {
		Class<?> c = Stu.class;
		// 1. 获取 当前类 中所有 public 修饰的构造方法
		Constructor<?>[] constructors = c.getConstructors();
		// 2. 获取 当前类中 所有构造方法 (含 private)
		constructors = c.getDeclaredConstructors();
		for (Constructor<?> cr : constructors) {
			System.out.println(cr);
		}
		System.out.println("--------------------");
		try {
			// 3. 根据构造方法的参数列表 获取 当前类 中对应的  public 修饰的构造方法
			// 传入对应的构造函数的参数列表
			//Constructor<?> cr = c.getConstructor();// 获取无参构造
			Constructor<?> cr = c.getConstructor(String.class, int.class);
			System.out.println(cr);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		try {
			// 4. 根据构造方法的参数列表 获取 当前类中 指定构造方法 (含 private)
			Constructor<?> cr = c.getDeclaredConstructor(int.class, String.class);
			System.out.println(cr);
			
			// 访问受限制时, 可以设置 允许访问, 这样就可以正常访问方法
			cr.setAccessible(true);
			
			// 调用构造方法, 创建对象, 传入对应的参数值
			Object instance = cr.newInstance(24, "tom");
			System.out.println("instance:" + instance);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 创建对象，并设置该对象指定属性的值
	 * @param c 对象的类型
	 * @param fieldName 对象的属性名
	 * @param value 属性对应的值
	 * @return 返回处理好的对象, 如果处理失败, 返回 null
	 */
	public static <T> T initObject(Class<T> c, String fieldName, Object value) {
		try {
			// 无参构造
			T t = c.newInstance();
			// 获取对应属性
			Field field = c.getDeclaredField(fieldName);
			// 允许访问(那些受限制的)属性
			field.setAccessible(true);
			// 设置值
			field.set(t, value);
			return t;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return null;
	}
	
}
